tamAutoQuest = LibStub("AceAddon-3.0"):NewAddon("tamAutoQuest", "AceConsole-3.0", "AceEvent-3.0")

local addon = tamAutoQuest

local options = {
    name = "tamAutoQuest",
    handler = tamAutoQuest,
    type = 'group',
    args = {
        enable = {
            name = "Enable",
            type = "toggle",
            desc = "Enables and disables this addon.",
            set = "SetEnable",
            get = "GetEnable",
        },
        debug = {
            name = "Debug",
            type = "toggle",
            desc = "Enables and disables debug mode.",
            set = "SetDebug",
            get = "GetDebug",
        },
    },
}

local defaults = {
    profile = {
        debug = false,
    },
}

function addon:printDebug(functionName, message)
    if self.db.profile.debug then
        self:Print("<<" .. functionName .. ">> " .. tostring(message))
    end
end

local optionsFrame
function addon:OnInitialize()
    -- Called when the addon is loaded
    self.db = LibStub("AceDB-3.0"):New("tamDB", defaults, "Default")
    
    LibStub("AceConfig-3.0"):RegisterOptionsTable("tamAutoQuest", options)
    self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("tamAutoQuest", "tamAutoQuest")
    self:RegisterChatCommand("tamautoquest", "ChatCommand")
    self:RegisterChatCommand("taq", "ChatCommand")
    
    self.hasIcon = true
	self.title = "tamAutoQuest"
end

function addon:OnEnable()
    -- Called when the addon is enabled
    addon:printDebug("OnEnable", "start")
    self:RegisterEvent("GOSSIP_SHOW")
    self:RegisterEvent("QUEST_GREETING")
    self:RegisterEvent("QUEST_DETAIL")
    self:RegisterEvent("QUEST_PROGRESS")
    self:RegisterEvent("QUEST_COMPLETE")
    self:RegisterEvent("QUEST_FINISHED")
    self:RegisterEvent("PLAYER_TARGET_CHANGED")
    self:RegisterEvent("QUEST_ACCEPT_CONFIRM")
end

function addon:OnDisable()
    -- Called when the addon is disabled
end

local lastQuestIndex = 0
function addon:RotateThruQuests()
    local numActive,numAvailable = select("#", GetGossipActiveQuests())/3, select("#", GetGossipAvailableQuests())/3
    local numActive2,numAvailable2 = GetNumActiveQuests(), GetNumAvailableQuests()
    addon:printDebug("", numActive .. " active quests, " .. numAvailable .. " available quests")
    addon:printDebug("", numActive2 .. " active quests, " .. numAvailable2 .. " available quests")

    local curQuestCount = numActive + numAvailable + numActive2 + numAvailable2
    local curQuestIndex = lastQuestIndex + 1
    addon:printDebug("", "curQuestIndex = " .. curQuestIndex)

    --reset curQuestIndex back to 1 if we're over the curQuestCount count
    if curQuestIndex > curQuestCount then
        addon:printDebug("", "curQuestIndex reset to 1")
        curQuestIndex = 1
    end

    --save lastQuestIndex
    lastQuestIndex = curQuestIndex

    if curQuestIndex <= numActive then
        addon:printDebug("", "Selecting gossip active quest " .. curQuestIndex)
        SelectGossipActiveQuest(curQuestIndex)
    elseif curQuestIndex <= numActive + numAvailable then
        addon:printDebug("", "Selecting gossip available quest " .. curQuestIndex)
        SelectGossipAvailableQuest(curQuestIndex - numActive)
    elseif curQuestIndex <= numActive + numAvailable + numActive2 then
        addon:printDebug("", "Selecting active quest " .. curQuestIndex)
        SelectActiveQuest(curQuestIndex - numActive - numAvailable)
    else
        addon:printDebug("", "Selecting available quest " .. curQuestIndex)
        SelectAvailableQuest(curQuestIndex - numActive - numAvailable - numActive2)
    end

    --attempt to prevent skipping a quest in the rotation
    --when a quest is completed or accepted and causes the total number of quests on the target to decrease
    numActive,numAvailable = select("#", GetGossipActiveQuests())/3, select("#", GetGossipAvailableQuests())/3
    numActive2,numAvailable2 = GetNumActiveQuests(), GetNumAvailableQuests()
    local newQuestCount = numActive + numAvailable + numActive2 + numAvailable2
    if newQuestCount < curQuestCount then
        lastQuestIndex = lastQuestIndex - 1
    end
end

function addon:QUEST_ACCEPT_CONFIRM(playerName, questTitle)
    ConfirmAcceptQuest()
end

function addon:QUEST_GREETING()
    addon:printDebug("QUEST_GREETING", "event")
    if (IsShiftKeyDown())then return end
    
    addon:RotateThruQuests()
end

function addon:GOSSIP_SHOW()
    addon:printDebug("GOSSIP_SHOW", "event")
    if (IsShiftKeyDown())then return end

    addon:RotateThruQuests()
end

function addon:QUEST_DETAIL()
    addon:printDebug("QUEST_DETAIL", "event")
    if (IsShiftKeyDown())then return end

    AcceptQuest()
end

function addon:QUEST_PROGRESS()
    addon:printDebug("QUEST_PROGRESS", "event")
    if (IsShiftKeyDown())then return end
    
    if IsQuestCompletable() then
        CompleteQuest()
    end
end

function addon:QUEST_COMPLETE()
    addon:printDebug("QUEST_COMPLETE", "event")

    if (IsShiftKeyDown())then return end

    if GetNumQuestChoices() > 0 then
        return
    else
        GetQuestReward(0)
    end
end

function addon:QUEST_FINISHED()
    addon:printDebug("QUEST_FINISHED", "event")
end

function addon:PLAYER_TARGET_CHANGED()
    --addon:printDebug("PLAYER_TARGET_CHANGED", "event")
    lastQuestIndex = 0
end

function addon:SetEnable(info,val)
    if val then
        self.Enable(self)
    else
        self.Disable(self)
    end
end

function addon:GetEnable(info)
    return self:IsEnabled()
end

function addon:SetDebug(info,val)
    self.db.profile.debug = val
end

function addon:GetDebug(info)
    return self.db.profile.debug
end

function addon:ChatCommand(input)
    if not input or input:trim() == "" then
        InterfaceOptionsFrame_OpenToFrame(self.optionsFrame)
    else
        LibStub("AceConfigCmd-3.0").HandleCommand(tamAutoQuest, "taq", "tamAutoQuest", input)
    end
end